﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1.Work4
{
    public class Customer
    {
        public string Name { get; set; }

        public Customer(string name)
        {
            Name = name;
        }

        public override string ToString() => Name;
    }

    // 商品类
    public class Product
    {
        public string Name { get; set; }
        public double Price { get; set; }

        public Product(string name, double price)
        {
            Name = name;
            Price = price;
        }

        public override string ToString() => Name + " (" + Price + " 元)";
    }

    // 订单明细
    public class OrderDetail
    {
        public Product Product { get; set; }
        public int Quantity { get; set; }

        public OrderDetail(Product product, int quantity)
        {
            Product = product;
            Quantity = quantity;
        }

        public double Amount => Product.Price * Quantity;

        public override bool Equals(object obj)
        {
            return obj is OrderDetail detail &&
                   Product.Name == detail.Product.Name;
        }

        public override int GetHashCode()
        {
            return Product.Name.GetHashCode();
        }

        public override string ToString() =>
            $"{Product.Name} x {Quantity} = {Amount:F2} 元";
    }

    // 订单类
    public class Order
    {
        public int OrderId { get; set; }
        public Customer Customer { get; set; }
        private readonly List<OrderDetail> details = new List<OrderDetail>();

        public Order(int orderId, Customer customer)
        {
            OrderId = orderId;
            Customer = customer;
        }

        public IReadOnlyList<OrderDetail> Details => details;

        public double TotalAmount => details.Sum(d => d.Amount);

        public void AddDetail(OrderDetail detail)
        {
            if (details.Contains(detail))
                throw new ApplicationException("订单明细已存在: " + detail.Product.Name);
            details.Add(detail);
        }

        public void RemoveDetail(string productName)
        {
            var detail = details.FirstOrDefault(d => d.Product.Name == productName);
            if (detail == null)
                throw new KeyNotFoundException("未找到订单明细: " + productName);
            details.Remove(detail);
        }

        public override bool Equals(object obj)
        {
            return obj is Order order && OrderId == order.OrderId;
        }

        public override int GetHashCode() => OrderId.GetHashCode();

        public override string ToString()
        {
            var detailsStr = string.Join("; ", details.Select(d => d.ToString()));
            return $"订单编号: {OrderId}, 客户: {Customer}, 总金额: {TotalAmount:F2} 元\n  明细: {detailsStr}";
        }
    }

    // 订单服务
    public class OrderService
    {
        private List<Order> orders = new List<Order>();

        public void AddOrder(Order order)
        {
            if (orders.Contains(order))
                throw new ApplicationException("订单已存在: " + order.OrderId);
            orders.Add(order);
        }

        public void RemoveOrder(int orderId)
        {
            var order = orders.FirstOrDefault(o => o.OrderId == orderId);
            if (order == null)
                throw new KeyNotFoundException("未找到订单: " + orderId);
            orders.Remove(order);
        }

        public void UpdateOrder(Order updated)
        {
            var idx = orders.FindIndex(o => o.OrderId == updated.OrderId);
            if (idx < 0)
                throw new KeyNotFoundException("无法修改，未找到订单: " + updated.OrderId);
            orders[idx] = updated;
        }

        public void Sort()
        {
            orders = orders.OrderBy(o => o.OrderId).ToList();
        }

        public void Sort(Comparison<Order> comparison)
        {
            orders.Sort(comparison);
        }

        public IEnumerable<Order> QueryById(int id) =>
            orders.Where(o => o.OrderId == id).OrderBy(o => o.TotalAmount);

        public IEnumerable<Order> QueryByProductName(string productName) =>
            orders.Where(o => o.Details.Any(d => d.Product.Name == productName))
                  .OrderBy(o => o.TotalAmount);

        public IEnumerable<Order> QueryByCustomer(string customerName) =>
            orders.Where(o => o.Customer.Name == customerName)
                  .OrderBy(o => o.TotalAmount);

        // 按金额范围
        public IEnumerable<Order> QueryByAmountRange(double min, double max) =>
            orders.Where(o => o.TotalAmount >= min && o.TotalAmount <= max)
                  .OrderBy(o => o.TotalAmount);

        public IEnumerable<Order> GetAllOrders() => orders;
    }

    class work41
    {
        static OrderService service = new OrderService();

        static void Main()
        {
            bool exit = false;
            while (!exit)
            {
                Console.WriteLine("\n订单管理系统:");
                Console.WriteLine("1. 添加订单");
                Console.WriteLine("2. 删除订单");
                Console.WriteLine("3. 修改订单");
                Console.WriteLine("4. 查询订单");
                Console.WriteLine("5. 显示所有订单");
                Console.WriteLine("6. 排序订单");
                Console.WriteLine("0. 退出");
                Console.Write("请选择操作: ");

                switch (Console.ReadLine())
                {
                    case "1": AddOrder(); break;
                    case "2": RemoveOrder(); break;
                    case "3": UpdateOrder(); break;
                    case "4": QueryOrder(); break;
                    case "5": ShowAll(); break;
                    case "6": SortOrders(); break;
                    case "0": exit = true; break;
                    default: Console.WriteLine("无效选项"); break;
                }
            }
        }

        static void AddOrder()
        {
            try
            {
                Console.Write("输入订单编号: ");
                int id = int.Parse(Console.ReadLine());
                Console.Write("输入客户名称: ");
                string cust = Console.ReadLine();
                Order order = new Order(id, new Customer(cust));

                Console.Write("添加多少条明细? ");
                int n = int.Parse(Console.ReadLine());
                for (int i = 0; i < n; i++)
                {
                    Console.Write("商品名称: "); var name = Console.ReadLine();
                    Console.Write("单价: "); var price = double.Parse(Console.ReadLine());
                    Console.Write("数量: "); var qty = int.Parse(Console.ReadLine());
                    order.AddDetail(new OrderDetail(new Product(name, price), qty));
                }
                service.AddOrder(order);
                Console.WriteLine("添加成功!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("添加订单失败: " + ex.Message);
            }
        }

        static void RemoveOrder()
        {
            try
            {
                Console.Write("输入要删除的订单编号: ");
                int id = int.Parse(Console.ReadLine());
                service.RemoveOrder(id);
                Console.WriteLine("删除成功!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("删除订单失败: " + ex.Message);
            }
        }

        static void UpdateOrder()
        {
            try
            {
                Console.Write("输入要修改的订单编号: ");
                int id = int.Parse(Console.ReadLine());
                Console.Write("输入新的客户名称: ");
                string cust = Console.ReadLine();
                Order order = new Order(id, new Customer(cust));
                Console.Write("新的明细数量: ");
                int m = int.Parse(Console.ReadLine());
                for (int i = 0; i < m; i++)
                {
                    Console.Write("商品: "); var name = Console.ReadLine();
                    Console.Write("价钱: "); var price = double.Parse(Console.ReadLine());
                    Console.Write("数量: "); var qty = int.Parse(Console.ReadLine());
                    order.AddDetail(new OrderDetail(new Product(name, price), qty));
                }
                service.UpdateOrder(order);
                Console.WriteLine("修改成功!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("修改订单失败: " + ex.Message);
            }
        }

        static void QueryOrder()
        {
            Console.WriteLine("查询方式: 1-订单号 2-商品名称 3-客户 4-金额范围");
            var key = Console.ReadLine();
            IEnumerable<Order> result = null;
            try
            {
                switch (key)
                {
                    case "1":
                        Console.Write("订单号: ");
                        int id = int.Parse(Console.ReadLine());
                        result = service.QueryById(id);
                        break;
                    case "2":
                        Console.Write("商品名称: ");
                        string pname = Console.ReadLine();
                        result = service.QueryByProductName(pname);
                        break;
                    case "3":
                        Console.Write("客户名称: ");
                        string cname = Console.ReadLine();
                        result = service.QueryByCustomer(cname);
                        break;
                    case "4":
                        Console.Write("最小金额: ");
                        double min = double.Parse(Console.ReadLine());
                        Console.Write("最大金额: ");
                        double max = double.Parse(Console.ReadLine());
                        result = service.QueryByAmountRange(min, max);
                        break;
                    default:
                        Console.WriteLine("未知查询方式"); return;
                }
                foreach (var o in result) Console.WriteLine(o);
            }
            catch (Exception ex)
            {
                Console.WriteLine("查询失败: " + ex.Message);
            }
        }

        static void ShowAll()
        {
            var all = service.GetAllOrders();
            if (!all.Any()) Console.WriteLine("无订单");
            foreach (var o in all) Console.WriteLine(o);
        }

        static void SortOrders()
        {
            Console.WriteLine("1-默认(订单号) 2-自定义(按总金额)");
            var c = Console.ReadLine();
            if (c == "1") service.Sort();
            else service.Sort((o1, o2) => o1.TotalAmount.CompareTo(o2.TotalAmount));
            Console.WriteLine("排序完成");
        }
    }
}
